package com.liqi.frame.comm.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 通道过滤器（读取request信息并重新放入request）
 * request refill
 * 用于在 request 和 response 中加入统一的动作
 */
@Slf4j
public class ChannelFilter extends OncePerRequestFilter {

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return new AntPathMatcher().match("/swagger-resources/**", request.getServletPath()) ||
                new AntPathMatcher().match("/webjars/**", request.getServletPath()) ||
                new AntPathMatcher().match("/swagger-ui.html", request.getServletPath()) ||
                new AntPathMatcher().match("/v2/**", request.getServletPath()) ||
                new AntPathMatcher().match("/csrf", request.getServletPath());
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        RequestWrapper requestWrapper = null;
        String contentType = request.getContentType() == null ? "" : request.getContentType();

        if (!contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE)) {
            requestWrapper = new RequestWrapper(request);

            log.info("call the "+request.getRequestURI());
            String body = requestWrapper.getBody();

            JSONObject jsonObject = JSON.parseObject(body);
            if (jsonObject!=null) {
                JSONObject jsonObjectLog = new JSONObject();
                jsonObject.forEach((key, value) -> {
                    if ("token".equals(key)) {
                        jsonObjectLog.put(key, "*************************");
                    } else {
                        jsonObjectLog.put(key, value);
                    }
                });
                log.info("The request content is:\n "+jsonObjectLog);
            }
        }

        ResponseWrapper responseWrapper = new ResponseWrapper(response);
        if (requestWrapper == null) {
            filterChain.doFilter(request, response);
        } else {
            filterChain.doFilter(requestWrapper, responseWrapper);
            if (!contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE)) {
                String result = new String(responseWrapper.getResponseData());
                log.info("The response content is:\n " + result);

                ServletOutputStream outputStream = response.getOutputStream();
                outputStream.write(result.getBytes());
                outputStream.flush();
                outputStream.close();
            }
        }
    }
}
